<template>
  <el-dialog
    :visible.sync="dialogVisible"
    :before-close="handleDialogClose"
    :append-to-body="appendToBody"
    :class="{'mobile-page-dialog':showMobilePage}"
    modal-append-to-body
    lock-scroll
    class="subcribe-common-dialog normal-common-dialog-size"
  >
    <div class="create-info-box">
      <DialogTitle title="选择交接人" font-size="16px" />
      <el-form ref="handoverChangeForm" :model="handoverForm" :rules="formRules" label-position="right">
        <div :class="{'flex-column': showMobilePage}" class="form-content">
          <el-form-item :label-width="showMobilePage?'80px':'65px'" label="交接人" prop="handoverId" style="white-space: nowrap;">
            <el-select
              ref="selectHandoverIdRef"
              v-model="handoverForm.handoverId"
              :filter-method="filterApproverData"
              :disabled="handoverDisable"
              filterable
              size="small"
              clearable
              placeholder="姓名/工号"
              popper-class="global-select-down"
              class="handover-select filterableSelect _remoteRequest"
              @hook:mounted="cancalReadOnly($event, 'selectHandoverIdRef')"
              @visible-change="cancalReadOnly($event, 'selectHandoverIdRef')"
              @change="handleHandoverChange"
              @clear="filterApproverData">
              <el-option
                v-for="item in nodeApprovers.items"
                :key="item.id"
                :label="`${item.userName} ${item.jobNumber ? '(' + item.jobNumber + ')' : ''}`"
                :value="item.id"/>
              <div v-if="userLoading" class="loading-container"><i class="el-icon-loading"/></div>
            </el-select>
          </el-form-item>
          <div class="arrow-icon">变更为</div>
          <el-form-item label-width="80px" label="被交接人" prop="recipientId">
            <el-select
              ref="selectUserRef"
              v-model="handoverForm.recipientId"
              :filter-method="filterUserData"
              filterable
              size="small"
              clearable
              placeholder="姓名/工号"
              popper-class="global-select-down"
              class="user-select filterableSelect _remoteRequest"
              @hook:mounted="cancalReadOnly($event, 'selectUserRef')"
              @visible-change="cancalReadOnly($event, 'selectUserRef')"
              @clear="filterUserData">
              <el-option
                v-for="item in userList.items"
                :key="item.id"
                :label="`${item.userName}（${item.jobNumber}）`"
                :value="item.id"/>
              <div v-if="userLoading" class="loading-container"><i class="el-icon-loading"/></div>
            </el-select>
          </el-form-item>
        </div>
      </el-form>
    </div>
    <div class="contract-info-box">
      <DialogTitle title="设置交接项" font-size="16px">
        <span v-if="!showMobilePage" class="contract-info-tip">注意：未勾选的审批节点将不进行人员交接</span>
      </DialogTitle>
      <div v-loading="contentLoading" v-if="handoverInfoList.length || contentLoading" class="contract-info-content">
        <template v-for="handoverItem in handoverInfoList">
          <ProcessChangeNode
            :key="handoverItem.businessId"
            :node-data="handoverItem"
            :module-id="moduleId"
            :business-type="businessType"
            v-model="selectNodeData[handoverItem.businessId]"
          />
        </template>
      </div>
      <div v-else class="contract-info-empty">
        <img :src="EmptyImg" alt="暂无数据">
        <div>{{ hasPermission?'请先选择交接人' : '暂无可交接项' }}</div>
      </div>
    </div>
    <div class="dialog-footer">
      <el-button :disabled="submitBtnDisabled" size="small" class="ok" type="primary" @click="formValidate">提交</el-button>
      <el-button class="cancel-btn-style" size="small" type="info" @click="handleDialogClose">取消</el-button>
    </div>
  </el-dialog>
</template>

<script>
import DialogTitle from '@/components/Title';
import { getList, queryHandoverList } from '@/api/user';
import { getHandoverInfoList, processHandoverModify } from '@/api/legal';
import { getCostHandoverInfoList, costHandoverModify, queryCostHandoverList } from '@/api/costManage';
import EmptyImg from '@/assets/empty-table-data.png';
import ProcessChangeNode from './module/processChangeNode';
import { BUSINESS_TYPE } from '@/utils/const/process';
import { APPROVE_CHANGE_PERMISSION_OF_MODULE } from '@/utils/const';
import { mapState } from 'vuex';
import { hasRouteAuth } from '@/utils/permission';

export default {
  name: 'ApproverChange',
  components: {
    DialogTitle,
    ProcessChangeNode
  },
  props: {
    loading: {
      type: Boolean,
      default: false
    },
    ids: {
      type: [String, Number],
      default: ''
    },
    businessType: {
      type: Number,
      default: BUSINESS_TYPE.CONTRACT
    },
    hasApproverChange: {
      type: Boolean,
      default: false
    },
    moduleId: {
      type: Number | String,
      default: null
    },
    appendToBody: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      EmptyImg,
      dialogVisible: false,
      isUploading: false,
      contentLoading: false,
      curPage: 1,
      handoverForm: {
        handoverId: '',
        recipientId: ''
      },
      nodeApprovers: {
        items: []
      }, // 所有节点审批人员
      userList: [], // 公司所有在职人员
      userLoading: false,
      formRules: {
        handoverId: [{ required: true, trigger: 'change', message: '请选择交接人' }],
        recipientId: [{ required: true, trigger: 'change', message: '请选择被交接人' }]
      },
      selectNodeData: {}, // 选中的节点
      handoverInfoList: [],
      handoverDisable: false,
      hasPermission: true
    };
  },
  computed: {
    ...mapState({
      'showMobilePage': state => state.app.showMobilePage,
      'userInfo': state => state.user.userInfo
    }),
    submitBtnDisabled() {
      if (!this.handoverForm.handoverId || !this.handoverForm.recipientId || this.isUploading) {
        return true;
      }
      return !this.getSelectedIds().length;
    }
  },
  watch: {
    dialogVisible(val) {
      if (val) {
        this.getUser();
        this.queryHandoverList();
        this.bindLoadMoreEvent();
        this.bindLoadMoreEvent(false);
        this.setDefaultHandover();
      }
    }
  },
  methods: {
    bindLoadMoreEvent(isApprover = true) {
      const timer = setTimeout(() => {
        const selectClassName = isApprover ? 'handover-select' : 'user-select';
        const selectWrapDom = document.querySelectorAll(`.${selectClassName} .el-select-dropdown__wrap`);
        const selectWrapList = Array.from(selectWrapDom);
        selectWrapList.forEach(dom => {
          const that = this;
          dom.addEventListener('scroll', function() {
            const CONDITION = this.scrollHeight - this.scrollTop <= this.clientHeight;
            CONDITION && that.userLoadMore(isApprover);
          });
        });
        if (isApprover) {
          window.remoteRequest('._remoteRequest', this.filterApproverData);
        } else {
          window.remoteRequest('._remoteRequest', this.filterUserData);
        }
        clearTimeout(timer);
      });
    },
    // 获取交接人和被交接人的列表
    userLoadMore(isApprover = true) {
      const list = isApprover ? this.nodeApprovers : this.userList;
      if (list.items && list.total) {
        const isMax = list.items.length >= list.total;
        if (!isMax && !this.userLoading) {
          isApprover ? this.queryHandoverList(false) : this.getUser(false);
        }
      }
    },
    setDefaultHandover() { // 没有权限交接人默认选择当前用户，并禁用交接人
      let hasPermission = true;
      this.handoverDisable = false;
      this.hasPermission = true;
      if (this.businessType === BUSINESS_TYPE.APPROVAL) {
        hasPermission = this.hasApproverChange;
      } else {
        hasPermission = hasRouteAuth(this.getAuthUrl());
      }
      if (!hasPermission) {
        this.nodeApprovers.items = [{ id: this.userInfo.id, userName: this.userInfo.userName }];
        this.handoverForm.handoverId = this.userInfo.id;
        this.handleHandoverChange(this.handoverForm.handoverId);
        this.handoverDisable = true;
        this.hasPermission = false;
      }
    },
    filterApproverData(val = '') {
      this.queryHandoverList(true, val);
    },
    filterUserData(val = '') {
      this.getUser(true, val);
    },
    // 切换交接人
    handleHandoverChange(id) {
      this.selectNodeData = {};
      if (!id) {
        this.handoverInfoList = [];
        return;
      }
      const params = Object.create(null);
      params.businessType = this.businessType;
      params.ids = this.ids + '';
      params.handoverId = id;
      this.contentLoading = true;
      // 成本转交的接口与含审批流的审批模块不一样
      const requestApi = this.businessType === BUSINESS_TYPE.COST ? getCostHandoverInfoList : getHandoverInfoList;
      requestApi(params).then(res => {
        if (res.code === 200) {
          this.handoverInfoList = res.data;
        }
        this.contentLoading = false;
      }).catch(_ => {
        this.contentLoading = false;
      });
    },
    // 获取选中合同的节点审批人列表
    queryHandoverList(reset = true, userName = '') {
      this.userLoading = true;
      this.curPage = reset ? 1 : ++this.curPage;
      const params = Object.create(null);
      params.perPage = 15;
      params.page = this.curPage;
      params.ids = this.ids + '';
      params.businessType = this.businessType;
      params.userName = userName;
      params.authUrl = this.getAuthUrl();
      const requestApi = this.businessType === BUSINESS_TYPE.COST ? queryCostHandoverList : queryHandoverList;
      requestApi(params).then(({ data }) => {
        this.userLoading = false;
        if (!reset && this.nodeApprovers.items) {
          data.items = this.nodeApprovers.items.concat(data.items);
        }
        this.nodeApprovers = data;
      });
    },
    // 固定表单传对应审批转交权限id，用来过滤
    getAuthUrl() {
      return APPROVE_CHANGE_PERMISSION_OF_MODULE[this.businessType] || '';
    },
    getUser(reset = true, userName = '', type = 1) {
      this.userLoading = true;
      this.curPage = reset ? 1 : ++this.curPage;
      const userStatus = 1; // 仅筛选用户状态为启用的
      getList(this.curPage, 15, { userName, type, userStatus }).then(({ data }) => {
        this.userLoading = false;
        if (!reset && this.userList.items) {
          data.items = this.userList.items.concat(data.items);
        }
        this.userList = data;
      });
    },
    handleDialogClose() {
      this.dialogVisible = false;
      this.$refs['handoverChangeForm'].resetFields();
      this.handoverInfoList = [];
    },
    formValidate() {
      this.$refs['handoverChangeForm'].validate(valid => {
        valid && this.handleConfirm();
      });
    },
    // 获取每个交接项的节点
    getSelectedIds() {
      const selectedKeys = Object.keys(this.selectNodeData);
      if (!selectedKeys.length) {
        return [];
      }
      const result = [];
      selectedKeys.forEach(key => {
        if (this.selectNodeData[key] && this.selectNodeData[key].length) {
          const obj = Object.create(null);
          obj.id = key;
          obj.nodeIds = this.selectNodeData[key].join(',');
          result.push(obj);
        }
      });
      return result;
    },
    // 提交
    handleConfirm() {
      if (this.handoverForm.handoverId === this.handoverForm.recipientId) {
        this.$message.warning('交接人和被交接人不能相同');
        return;
      }
      this.isUploading = true;
      const params = Object.create(null);
      params.businessType = this.businessType;
      params.handoverId = this.handoverForm.handoverId;
      params.recipientId = this.handoverForm.recipientId;
      params.modifyList = this.getSelectedIds();
      const requestApi = this.businessType === BUSINESS_TYPE.COST ? costHandoverModify : processHandoverModify;
      requestApi(params).then(() => {
        this.isUploading = false;
        this.handleDialogClose();
        this.$message.success('变更成功');
        this.$emit('changeCallBack');
      }).catch(_ => {
        this.isUploading = false;
        this.handleDialogClose();
      });
    },
    cancalReadOnly(onOff, ref) {
      if (this.showMobilePage) {
        this.$nextTick(() => {
          if (!onOff && this.$refs[ref]) {
            const input = this.$refs[ref].$el.querySelector('.el-input__inner');
            input.removeAttribute('readonly');
          }
        });
      }
    }
  }
};
</script>

<style lang="scss" scoped>
::v-deep .el-select {
  width: 240px;
}
::v-deep .el-form-item__label {
  padding-right: 5px !important;
}
.create-info-box {
  margin-bottom: 32px;
  .form-content {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-top: 16px;
    .el-form-item {
      margin-bottom: 0 !important;
    }
  }
}

.contract-info-box {
  .contract-info-content {
    max-height: 350px;
    min-height: 60px;
    width: 100%;
    overflow-y: auto;
  }
  .contract-info-tip {
    color: #999;
    font-size: 12px;
    margin-left: 8px;
    font-weight: normal;
  }
  .contract-info-empty {
    width: 100%;
    text-align: center;
    margin: 24px 0;
    color: #999;
    > img {
      width: 112px;
      margin-bottom: 8px;
    }
  }
}
.loading-container {
  width: 100%;
  text-align: center;
  i {
    color: #999;
  }
}
.arrow-icon {
  height: 20px;
  line-height: 20px;
  background: #D9F9EF;
  color: #31CC9C;
  font-size: 13px;
  display: flex;
  align-items: center;
  padding: 3px 5px 3px 12px;
  position: relative;
}
.arrow-icon::after {
  content: '';
  border: 15px solid transparent;
  //border-left: 20px solid #ffefe6;
  border-left: 20px solid #D9F9EF;
  position: absolute;
  right: -34px;
  top: -5px;
}
.dialog-footer {
  display: flex;
  justify-content: center;
  margin-top: 25px;
  .ok {
    width: 80px;
    font-size: 14px;
    padding: 8px 20px;
  }
  .cancel-btn-style {
    font-size: 14px;
    width: 80px;
    padding: 8px 20px;
    margin-left: 16px !important;
  }
}
.mobile-page-dialog {
  &::v-deep {
    .el-dialog {
      width: 100% !important;
      .el-dialog__close {
        right: -5px !important;
        top: -52px !important;
      }
    }
  }
}
.flex-column {
  flex-direction: column;
  align-items: flex-start;
  .arrow-icon {
    margin: 10px 0;
  }
}
</style>
